package com.newtouch.bxzs.database.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newtouch.bxzs.common.base.BaseErrorEnum;
import com.newtouch.bxzs.common.base.BaseException;
import com.newtouch.bxzs.common.base.model.Position;
import com.newtouch.bxzs.common.base.model.RolePositionMap;
import com.newtouch.bxzs.common.base.util.Assert;
import com.newtouch.bxzs.common.base.util.UserDetailUtil;
import com.newtouch.bxzs.database.constant.DataBaseConstant;
import com.newtouch.bxzs.database.mapper.PositionMapper;
import com.newtouch.bxzs.database.mapper.RolePositionMapMapper;
import com.newtouch.bxzs.database.mapper.UserPositionMapMapper;
import com.newtouch.bxzs.database.model.bo.PositionDetailBO;
import com.newtouch.bxzs.database.model.bo.PositionListBO;
import com.newtouch.bxzs.database.model.bo.RoleBO;
import com.newtouch.bxzs.database.model.vo.GetPositionListVO;
import com.newtouch.bxzs.database.model.vo.UpdatePositionStateVO;
import com.newtouch.bxzs.database.model.vo.UpdatePositionVO;
import com.newtouch.bxzs.database.service.PositionService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 岗位Service实现类:
 *
 * <p>
 * <b>History:</b>
 * <table border="1">
 * <tr>
 * <th>Date</th>
 * <th>Operator</th>
 * <th>Memo</th>
 * </tr>
 * <tr>
 * <td>2021/1/5 14:02</td>
 * <td>tianshangzhu</td>
 * <td>Create</td>
 * </tr>
 * </table>
 *
 * @author tianshangzhu
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
public class PositionServiceImpl implements PositionService {
    @Resource
    private PositionMapper positionMapper;

    @Resource
    private RolePositionMapMapper rolePositionMapMapper;

    @Resource
    private UserPositionMapMapper userPositionMapMapper;


    /**
     * 查询岗位列表信息
     *
     * @param getPositionListVO 参数
     * @return IPage<PositionListBO> 分页结果
     */
    @Override
    public IPage<PositionListBO> getPositionList(GetPositionListVO getPositionListVO) {
        // 设置分页参数
        Page<PositionListBO> page = new Page<>(getPositionListVO.getCurrentPage(), getPositionListVO.getPageSize());
        Integer enableFlag = null;
        if(StringUtils.isNotBlank(getPositionListVO.getEnableFlag())){
            enableFlag = Integer.valueOf(getPositionListVO.getEnableFlag());
        }
        return positionMapper.listAllPosition(page, getPositionListVO.getKeyWord(), getPositionListVO.getTerminalType(), enableFlag);
    }

    /**
     * 查询岗位详情信息
     *
     * @param positionId 岗位id
     * @return PositionDetailBO
     */
    @Override
    public PositionDetailBO getPositionDetail(String positionId) {
        // 查询岗位详情
        PositionDetailBO positionDetailBO = positionMapper.selectDetailById(positionId);
        // 查询岗位对应的角色
        List<RoleBO> roleBOList = positionMapper.listRoleByPositionId(positionId);
        positionDetailBO.setRoleList(roleBOList);
        return positionDetailBO;
    }

    /**
     * 添加/修改岗位信息
     *
     * @param updatePositionVO 参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePosition(UpdatePositionVO updatePositionVO) {
        // 必传参数校验
        Assert.notEmpty(updatePositionVO, "参数不能为空");
        String operationType = updatePositionVO.getOperationType();
        Assert.notEmpty(operationType, "操作类型不能为空");
        // 添加岗位或者修改岗位
        if (DataBaseConstant.OPERATION_TYPE_1.equals(operationType)) {
            // 添加或者修改
            Assert.notEmpty(updatePositionVO.getPositionName(), "参数【岗位名称】不能为空");
            Assert.notEmpty(updatePositionVO.getPositionCode(), "参数【岗位编码】不能为空");
            Assert.notEmpty(updatePositionVO.getPositionDescription(), "参数【岗位描述】不能为空");
            Assert.notEmpty(updatePositionVO.getRoleIds(), "参数【授权角色】不能为空");
            Assert.notEmpty(updatePositionVO.getTerminalType(), "参数【所属终端】不能为空");

            Position position = new Position();
            BeanUtils.copyProperties(updatePositionVO, position);
            // 启用/禁用
            if(Objects.equals(updatePositionVO.getEnableFlag(),DataBaseConstant.ENABLE)){
                position.setEnableFlag(true);
            }
            if(Objects.equals(updatePositionVO.getEnableFlag(),DataBaseConstant.DISABLE)){
                position.setEnableFlag(false);
            }
            // 岗位id
            String positionId = updatePositionVO.getPositionId();

            // positionId为空，为添加
            if (StringUtils.isBlank(positionId)) {
                // 表ASSISTANT_POSITION插入
                Date date = new Date();
                position.setCreateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
                position.setCreateTime(date);
                position.setDeleteFlag(false);
                position.setUpdateTime(date);
                position.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
                positionMapper.insert(position);
                positionId = position.getPositionId();
                // 维护ASSISTANT_ROLE_POSITION_MAP中间表
                insertIntoRolePositionMap(positionId, updatePositionVO.getRoleIds());
                return;
            }

            // 修改
            position.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
            position.setUpdateTime(new Date());
            positionMapper.updateById(position);
            // 调用修改中间表的方法
            dealPositionRoleMap(updatePositionVO.getPositionId(),updatePositionVO.getRoleIds());
        }

        // 只修改岗位授权
        if(DataBaseConstant.OPERATION_TYPE_2.equals(operationType)){
            // 调用修改中间表的方法
            dealPositionRoleMap(updatePositionVO.getPositionId(),updatePositionVO.getRoleIds());
        }
    }

    /**
     * 处理岗位角色中间表的数据
     * @param positionId 岗位id
     * @param roleIds 角色id集合
     */
    public void dealPositionRoleMap(String positionId, List<String> roleIds){
        // 先删除RolePositionMap中间表中的岗位id对应的角色数据
        positionMapper.deleteByPositionId(positionId);

        // 维护ASSISTANT_ROLE_POSITION_MAP中间表
        if(roleIds != null && !roleIds.isEmpty()){
            insertIntoRolePositionMap(positionId, roleIds);
        }
    }

    /**
     * 修改岗位状态
     *
     * @param vo 参数
     */
    @Override
    public void updateState(UpdatePositionStateVO vo) {
        // 判断该岗位是否被使用，使用中的岗位不能被禁用
        if(DataBaseConstant.DISABLE.equals(vo.getEnableFlag())&& userPositionMapMapper.checkExists(vo.getPositionId()) != null){
            throw new BaseException(BaseErrorEnum.ENABLE_USE);
        }
        positionMapper.updateState(vo);
    }

    /**
     * 批量删除岗位信息
     *
     * @param positionIdList 岗位id
     */
    @Override
    public void deletePosition(List<String> positionIdList) {
        Assert.notEmpty(positionIdList, "参数不能为空");
        // 判断所选岗位有没有启用中的岗位，启用中的岗位不可以删除
        int count = positionMapper.checkIsEnable(positionIdList);
        if (count < positionIdList.size()) {
            // 查出的结果比传入的少，说明有在启用状态的
            throw new BaseException(BaseErrorEnum.ENABLE_USE);
        }
        // 删除岗位信息
        positionMapper.modifyValidStatus(positionIdList);

        // 删除岗位角色中间表中数据
        rolePositionMapMapper.deleteByPositionIdBatch(positionIdList);
    }

    /**
     * RolePositionMap中间表插入
     *
     * @param positionId 岗位id
     * @param roleIds    角色id
     */
    public void insertIntoRolePositionMap(String positionId, List<String> roleIds) {
        List<RolePositionMap> list = new ArrayList<>();
        String userId = Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId();
        Date date = new Date();
        for (String roleId : roleIds) {
            RolePositionMap rolePositionMap = new RolePositionMap();
            rolePositionMap.setCreateUserId(userId);
            rolePositionMap.setCreateTime(date);
            rolePositionMap.setRoleId(roleId);
            rolePositionMap.setPositionId(positionId);
            list.add(rolePositionMap);
        }
        // 批量插入
        rolePositionMapMapper.saveBatch(list);
    }
}
